<template>
  <div class="three-box" id="three-box"></div>
</template>

<script setup>
import { getCurrentInstance, h, onMounted, onUnmounted, ref } from "vue";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { Group } from "three";
import * as dat from "dat.gui";
const threeBox = ref();

let { proxy } = getCurrentInstance();
let THREE = proxy.$THREE;

onMounted(() => {
  initThree();
});

const initThree = () => {
  const threeBox = document.getElementById("three-box");

  const scene = new THREE.Scene();

  const gui = new dat.GUI();

  const clock = new THREE.Clock();
  const material = new THREE.MeshNormalMaterial();
  const material2 = new THREE.MeshBasicMaterial({ color: 0xcccccc });

  const renderer = new THREE.WebGLRenderer();
  renderer.setSize(threeBox.clientWidth, threeBox.clientHeight);
  threeBox.appendChild(renderer.domElement);

  //汽车整体
  const car = new THREE.Group();

  //车身
  const carBody = new THREE.Group();

  const carBodyCube = new THREE.Mesh(
    new THREE.BoxGeometry(2, 0.5, 1),
    material
  );

  carBody.add(carBodyCube);
  car.add(carBody);

  // const carBody2 = new THREE.Mesh(
  //   new THREE.BoxGeometry(0.5, 0.1, 0.5),
  //   material2
  // );
  // carBody2.position.y = 0.3;
  // car.add(carBody2);

  //车轮
  const wheelGroup1 = new THREE.Group(
    new THREE.BoxGeometry(0.7, 0.7, 0.1),
    material
  );
  // const wheel1 = new THREE.Mesh(new THREE.BoxGeometry(0.7, 0.7, 0.1), material);
  // wheelGroup1.add(wheel1);
  wheelGroup1.position.set(-0.7, 0, 0.7);

  //轮胎
  const wheelCircle = new Group();
  const geoMetry = new THREE.TorusGeometry(0.5, 0.05, 5, 20);
  const mesh = new THREE.Mesh(geoMetry, material);

  wheelCircle.add(mesh);
  wheelGroup1.add(wheelCircle);

  //轮轴中心
  const circleCenter = new THREE.CylinderGeometry(0.01, 0.01, 0.12, 10, 12);
  const circleCentermesh = new THREE.Mesh(circleCenter, material);
  circleCentermesh.rotation.x = Math.PI / 2;
  wheelGroup1.add(circleCentermesh);

  //两个轮轴
  const roofGroup = new THREE.Group();
  const roof = new THREE.CylinderGeometry(0.05, 0.05, 1.5, 10, 20);
  const roofmesh = new THREE.Mesh(roof, material);
  roofmesh.rotation.x = Math.PI / 2;
  roofGroup.add(roofmesh);
  roofGroup.position.x = -0.7;

  const roofGroup2 = roofGroup.clone();
  roofGroup2.position.x = 0.7;

  car.add(roofGroup);
  car.add(roofGroup2);

  //轮轴
  let m = 10;
  const wheelAxle = new Group();
  for (let i = 0; i < m; i++) {
    let r = 0.5;
    const geoMetry = new THREE.BoxGeometry(0.05, r * 2, 0.05);
    const mesh = new THREE.Mesh(geoMetry, material);

    mesh.rotation.z = ((Math.PI * 2) / m) * i;

    wheelAxle.add(mesh);
  }
  wheelGroup1.add(wheelAxle);

  const wheelGroup2 = wheelGroup1.clone();
  wheelGroup2.position.set(-0.7, 0, -0.7);

  const wheelGroup3 = wheelGroup1.clone();
  wheelGroup3.position.set(0.7, 0, 0.7);

  const wheelGroup4 = wheelGroup1.clone();
  wheelGroup4.position.set(0.7, 0, -0.7);

  //车顶
  const carTop = new THREE.CylinderGeometry(0.57, 0.7, 0.3, 4, 1);
  const topMesh = new THREE.Mesh(carTop, material);

  topMesh.position.y = 0.4;
  topMesh.rotation.y = Math.PI / 4;
  car.add(topMesh);

  car.add(wheelGroup1);
  car.add(wheelGroup2);
  car.add(wheelGroup3);
  car.add(wheelGroup4);

  scene.add(car);

  const plane = new THREE.PlaneGeometry(100, 80);
  const planeMesh = new THREE.Mesh(plane, material2);
  planeMesh.rotation.x = -Math.PI / 2;
  planeMesh.position.y = -0.6;
  scene.add(planeMesh);

  const camera = new THREE.PerspectiveCamera(
    75,
    threeBox.clientWidth / threeBox.clientHeight,
    0.1,
    1000
  );
  camera.position.set(0, 3, 5);
  camera.lookAt(0, 0, 0);

  const guiFolder = gui.addFolder("相机位置");

  guiFolder.add(camera.position, "x", -5, 5, 0.01).name("相机位置-x");
  guiFolder.add(camera.position, "y", -5, 5, 0.01).name("相机位置-y");
  guiFolder.add(camera.position, "z", -5, 5, 0.01).name("相机位置-z");

  const orbitControls = new OrbitControls(camera, renderer.domElement); //鼠标交互、左键移动场景、滚轮放大缩小、右键平移

  //窗口自适应
  window.addEventListener('resize',()=>{
    let w = window.innerWidth;
    let h = window.innerHeight;

    camera.aspect = w / h;
    camera.updateProjectionMatrix();

    renderer.setSize(w, h);

  })

  function animate() {
    const time = clock.getElapsedTime();
    requestAnimationFrame(animate);

    car.position.x = (time % 4) - 2;
    wheelGroup1.rotation.z += 0.05;
    wheelGroup2.rotation.z += 0.05;
    wheelGroup3.rotation.z += 0.05;
    wheelGroup4.rotation.z += 0.05;

    orbitControls.update();


    const fogColor = 0x000000; // 雾化颜色，黑色
const fogNear = 1; // 近处的雾化距离
const fogFar = 10; // 远处的雾化距离
const fog = new THREE.Fog(fogColor, fogNear, fogFar);
scene.fog = fog;

    renderer.render(scene, camera);
  }

  animate();
};

onUnmounted(() => {

});
</script>

<style>
.three-box {
  position: fixed;
  top: 0;
  left: 200px;
  right: 0;
  bottom: 0;
  width: 100%;
}
</style>